/*/////////////////////////////////////////////////////////////////////////////////
/// An
///    ___   ____ ___ _____ ___  ____
///   / _ \ / ___|_ _|_   _/ _ \|  _ \
///  | | | | |  _ | |  | || | | | |_) |
///  | |_| | |_| || |  | || |_| |  _ <
///   \___/ \____|___| |_| \___/|_| \_\
///                              File
///
/// Copyright (c) 2008-2009 Ismail TARIM <ismail@royalspor.com> and the Ogitor Team
//
//This program is free software; you can redistribute it and/or modify it under
//the terms of the GNU Lesser General Public License as published by the Free Software
//Foundation; either version 2 of the License, or (at your option) any later
//version.
//
//This program is distributed in the hope that it will be useful, but WITHOUT
//ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
//FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
//
//You should have received a copy of the GNU Lesser General Public License along with
//this program; if not, write to the Free Software Foundation, Inc., 59 Temple
//Place - Suite 330, Boston, MA 02111-1307, USA, or go to
//http://www.gnu.org/copyleft/lesser.txt.
////////////////////////////////////////////////////////////////////////////////*/

#pragma once

#if OGRE_COMPILER == OGRE_COMPILER_MSVC
// Turn off warnings generated by this singleton implementation
#   pragma warning (disable : 4311)
#   pragma warning (disable : 4312)
#endif

#if defined ( OGRE_GCC_VISIBILITY )
#   pragma GCC visibility push(default)
#endif

namespace Ogitors
{
    //! Singleton class
    /*!  
        Template class for creating single-instance global classes.
    */
    template <typename T> class Singleton
    {
    protected:

        static T* ms_Singleton;             /** Handle to singleton-derived object */

    public:
        /**
        * Constructor
        */
        Singleton()
        {
            assert( !ms_Singleton );
#if defined( _MSC_VER ) && _MSC_VER < 1200
            int offset = (int)(T*)1 - (int)(Singleton <T>*)(T*)1;
            ms_Singleton = (T*)((int)this + offset);
#else
	    ms_Singleton = static_cast< T* >( this );
#endif
        }
        /**
        * Destructor
        */
        ~Singleton()
         {  
             assert( ms_Singleton );  
             ms_Singleton = 0;  
        }
        /**
        * Fetches singleton-derived object
        * @return singleton-derived object
        */
        static T& getSingleton()
		{	
            assert( ms_Singleton );  
            return ( *ms_Singleton ); 
        }
        
        /**
        * Fetches handle of singleton-derived object
        * @return handle of singleton-derived object
        */
        static T* getSingletonPtr()
		{ 
            return ms_Singleton; 
        }
    };
}
#if defined ( OGRE_GCC_VISIBILITY )
#   pragma GCC visibility pop
#endif
